#ifndef MATRIXDRAWING_HPP
#define MATRIXDRAWING_HPP

#include <QtOpenGL/QGLWidget>
#include <string>
#include <vector>
#include <QGLShaderProgram>
#include <QGLShader>

using std::vector;
using std::string;

class MatrixDrawing : public QGLWidget
{
    Q_OBJECT
public:
    float    u[3],v[3],n[3];
    float    translate[3];
    float    last_translate[3];
    float    rotation[3];
    float    last_rotation[3];
    float    translate_scaler[3];
    float    nearer_scaler;
    float    farer_scaler;
    float    fovy;
    float    aspect;
    explicit MatrixDrawing(QWidget *parent = 0);
    QSize sizeHint() const;
    void initializeGL();
    void paintGL();
    void resizeGL(int width, int height);
    void CameraRotation();
    void readfile(const char *Filename);
    struct userparameter
    {
        GLenum  facefront;
        float   color[3];
        float   rotation[3];
        float   translation[3];
        float   nearer;
        float   farer;
        GLenum  primitive;
        userparameter();
    };
    userparameter uipara;
    struct parameter
    {
        struct material
        {
            float   acolor[3];
            float   dcolor[3];
            float   scolor[3];
            float   shine;
        };
        struct triangle
        {
            struct vertex
            {
                float   pos[3];
                float   norm[3];
                int     matind;
            };
            vertex  v[3];
            float   fnorm[3];
            float   color[3];
        };
        string              name;
        int                 trinum;
        int                 marnum;
        vector<material>    mat;
        vector<triangle>    tri;
        float               pmax[3], pmin[3];
        float               distance;

    };
    parameter para;

    struct cameraparameter
    {
        float eye[3];
        float center[3];
        float up[3];
    };
    cameraparameter cpara;
    struct matrix
    {
        float m[16];
        matrix();
        void MatrixMult(float* b); // a = b* a
        void IdentityMatrix();
    };
    matrix modelviewmat,projectionmat;
    void getTMatrix(float x, float y, float z, GLfloat* temp);
    void getRMatrix(float x, float y, float z, GLfloat* temp);
    void CalcProjectionMatrix();

    struct matrixshader
    {
        QGLShaderProgram program;
        GLint  modelview_loc, projection_loc;
     };
    matrixshader mshader;
    void LoadShaders();

private:

signals:
    void initpara(double movxmin, double movxmax, double movymin, double movymax,
                  double movzmin, double movzmax, double nearmin, double farmax);

public slots:
    void Initalvalue();
    void setfilename(const char *fn);
    void setstruct(bool clockwise, char view);
    void setcolor(int red, int green, int blue);
    void settrans(float x, float y, float z);
    void setrotat(float x, float y, float z);
    void setclip(float nearer, float farer);
};

#endif // MATRIXDRAWING_HPP
